home *** CD-ROM | disk | FTP | other *** search
- ; NO.ASM -- Hides specified files from command that follows
- ; ======
-
- CSEG Segment
- Assume CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
- Org 002Ch
- Environment Label Word ; Segment of Environment is here
- Org 0080h
- Parameter Label Byte ; Parameter is here
- Org 0100h
- Entry: Jmp Begin ; Entry Point
-
- ; Most Data (some more at end of program)
- ; ---------------------------------------
-
- db "Copyright 1986 Ziff-Davis Publishing Co.",1Ah
- db " Programmed by Charles Petzold ",1Ah
- SyntaxMsg db "Syntax: NO filespec command [parameters]$"
- DosVersMsg db "NO: Needs DOS 2.0 +$"
- FileSpecMsg db "NO: Incorrect File Spec$"
- TooManyMsg db "NO: Too many files to hide$"
- MemAllocMsg db "NO: Allocation Problem$"
- CommandMsg db "NO: COMMAND Problem$"
- Delimiters db 9,' ,;='
- FileList dw ? ; Storage of found files
- FileCount dw 0 ; Count of found files
- FileListEnd dw ? ; End of storage of found files
- BreakState db ? ; Store original break state here
- Comspec db 'COMSPEC=' ; String for Environment search
- ParamBlock dw ? ; Parameter block for EXEC call
- dw ?, ?
- dw 5Ch, ?
- dw 6Ch, ?
- StackPointer dw ? ; Save SP during EXEC call
-
- ; Check DOS Version
- ; -----------------
-
- Begin: Mov AH, 30h ; Check for DOS Version
- Int 21h ; through DOS call
- Cmp AL, 2 ; See if it's 2.0 or above
- Jae DosVersOK ; If so, continue
-
- Mov DX, Offset DosVersMsg ; Error message
- ErrorExit: Mov AH, 9 ; Print String function call
- Int 21h ; Do it
- Int 20h ; And exit prematurely
-
- ; Parse Command Line to get NO File specification
- ; -----------------------------------------------
-
- ScanParam: Lodsb ; SUBROUTINE: Get byte
- Cmp AL, 13 ; See if end of parameter
- Je ErrorExit ; If so, exit
- Mov DI, Offset Delimiters ; Check if delimiter
- Mov CX, 5 ; There are 5 of them
- Repne Scasb ; Scan the string
- Ret ; And return
-
- DosVersOK: Mov DX, Offset SyntaxMsg ; Possible error msg
- Mov SI, 1+Offset Parameter ; NO Parameter string
- Cld ; Directions forward
-
- BegSearch: Call ScanParam ; Check byte in subroutine
- Je BegSearch ; If delimiter, keep searching
- Mov BX, SI ; Save pointer in BX
- Dec BX ; BX points to NO file spec
-
- EndSearch: Call ScanParam ; Check byte in subroutine
- Jne EndSearch ; If not delimiter, keep going
-
- ; Construct full FilePath and save down at end of program
- ; -------------------------------------------------------
-
- Dec SI ; Points after NO file spec
- Xchg SI, BX ; SI points to beg, BX to end
- Mov DI, Offset FullPath ; Points to destination
- Cmp Byte Ptr [SI + 1], ':' ; See if drive spec included
- Jnz GetDrive ; If not, must get the drive
- Lodsw ; Otherwise, grab drive spec
- And AL, 0DFh ; Capitalize drive letter
- Jmp Short SaveDrive ; And skip next section
-
- GetDrive: Mov AH, 19h ; Get current drive
- Int 21h ; through DOS
- Add AL, 'A' ; Convert to letter
- Mov AH, ':' ; Colon after drive letter
-
- SaveDrive: Stosw ; Save drive spec and colon
- Mov AL, '\' ; Directory divider byte
- Cmp [SI], AL ; See if spec starts at root
- Jz HaveFullPath ; If so, no need to get path
- Stosb ; Store that character
- Push SI ; Save pointer to parameter
- Mov SI, DI ; Destination of current path
- Mov DL, [SI - 3] ; Drive letter specification
- Sub DL, '@' ; Convert to number
- Mov AH, 47h ; Get current directory
- Int 21h ; through DOS
- Mov DX, Offset FileSpecMsg ; Possible error message
- Jc ErrorExit ; Exit if error
- Sub AL, AL ; Search for terminating zero
- Cmp [SI], AL ; Check if Root Directory
- Jz RootDir ; If so, don't use it
- Mov CX, 64 ; Number of bytes to search
- Repnz Scasb ; Do the search
- Dec DI ; DI points to last zero
- Mov AL, '\' ; Put a backslash in there
- Stosb ; So filespec can follow
- RootDir: Pop SI ; Get back SI
-
- HaveFullPath: Mov CX, BX ; End of NO file spec
- Sub CX, SI ; Number of bytes to transfer
- Rep Movsb ; Transfer them
- Sub AL, AL ; Terminating zero
- Stosb ; Save it
- Mov [FileList], DI ; Repository for found files
-
- ; Fix up parameter and ParamBlock for eventual COMMAND load
- ; ---------------------------------------------------------
-
- Sub BX, 4 ; Points to new param begin
- Mov AL, [Parameter] ; Old byte count of parameter
- Add AL, 80h ; Add beginning of old param
- Sub AL, BL ; Subtract beginning of new
- Mov AH, ' ' ; Space separator
- Mov Word Ptr [BX], AX ; Store it
- Mov Word Ptr [BX + 2], 'C/' ; Add /C to beginning of rest
- Mov AX, [Environment] ; Get environment segment
- Mov [ParamBlock], AX ; Save it
- Mov [ParamBlock + 2], BX ; Save parameter pointer
- Mov [ParamBlock + 4], CS ; Save segment of ParamBlock
- Mov [ParamBlock + 8], CS
- Mov [ParamBlock + 10], CS
-
- ; Find Files from NO File Specification
- ; -------------------------------------
-
- Mov DX, Offset DTABuffer ; Set File Find buffer
- Mov AH, 1Ah ; by calling DOS
- Int 21h
-
- Mov DI, [FileList] ; Address of destination
- Mov DX, Offset FullPath ; Search string
- Sub CX, CX ; Search Normal files only
- Mov AH, 4Eh ; Find first file
-
- FindFile: Int 21h ; Call DOS to find file
- Jnc Continue ; If no error continue
- Cmp AX, 18 ; If no more files
- Jz NoMoreFiles ; get out of the loop
- Mov DX, Offset FileSpecMsg ; Error message otherwise
- Jmp ErrorExit ; Exit and print message
-
- Continue: Mov AX, DI ; Address of destination
- Add AX, 512 ; See if near top of segment
- Jc TooManyFiles ; If so, too many files
- Cmp AX, SP ; See if getting too many
- Jb StillOK ; If not, continue
-
- TooManyFiles: Mov DX, Offset TooManyMsg ; Otherwise error message
- Jmp ErrorExit ; And terminate
-
- StillOK: Mov SI, 30+Offset DTABuffer ; Points to filename
- Call AsciizTransfer ; Transfer it to list
- Inc [FileCount] ; Kick up counter
- Mov AH, 4Fh ; Find next file
- Jmp FindFile ; By looping around
-
- NoMoreFiles: Mov [FileListEnd], DI ; Points after last file
- Mov DI, [FileList] ; Points to end of find string
- Mov CX, 64 ; Search up to 64 bytes
- Mov AL, '\' ; For the backslash
- Std ; Search backwards
- Repnz Scasb ; Do the search
- Mov Byte Ptr [DI + 2], 0 ; Stick zero in there
- Cld ; Fix up direction flag
-
- ; Stop Ctrl-Break Exits and Hide the files
- ; ----------------------------------------
-
- Mov AX,3300h ; Get Break State
- Int 21h ; By calling DOS
- Mov [BreakState],DL ; Save it
- Sub DL,DL ; Set it to OFF
- Mov AX,3301h ; Set Break State
- Int 21h ; By calling DOS
- Mov BL, 0FFh ; Value to AND attribute
- Mov BH, 02h ; Value to OR attribute
- Call ChangeFileMode ; Hide all the files
-
- ; Un-allocate rest of memory
- ; --------------------------
-
- Mov BX, [FileListEnd] ; Beyond this we don't need
- Add BX, 512 ; Allow 512 bytes for stack
- Mov SP, BX ; Set new stack pointer
- Add BX, 15 ; Prepare for truncation
- Mov CL,4 ; Prepare for shift
- Shr BX,CL ; Convert to segment form
- Mov AH,4Ah ; Shrink allocated memory
- Int 21h ; By calling DOS
- Mov DX,Offset MemAllocMsg ; Possible Error Message
- Jc ErrorExit2 ; Print it and terminate
-
- ; Search for Comspec in Environment
- ; ---------------------------------
-
- Push ES ; We'll be changing this
- Mov ES, [Environment] ; Set ES to Environment
- Sub DI, DI ; Start at the beginning
- Mov SI, Offset ComSpec ; String to search for
- Mov DX, Offset CommandMsg ; Possible error message
-
- TryThis: Cmp Byte Ptr ES:[DI], 0 ; See if points to zero
- Jz ErrorExit2 ; If so, we can't go on
- Push SI ; Temporarily save these
- Push DI
- Mov CX, 8 ; Search string has 8 chars
- Repz Cmpsb ; Do the string compare
- Pop DI ; Get back the registers
- Pop SI
- Jz LoadCommand ; If equals, we've found it
- Sub AL, AL ; Otherwise search for zero
- Mov CX, -1 ; For 'infinite' bytes
- Repnz Scasb ; Do the search
- Jmp TryThis ; And try the next string
-
- ; Load COMMAND.COM
- ; -----------------
-
- LoadCommand: Add DI, 8 ; so points after 'COMSPEC='
- Push DS ; Switch DS and ES registers
- Push ES
- Pop DS
- Pop ES
- Mov [StackPointer],SP ; Save Stack Pointer
- Mov DX, DI ; DS:DX = Asciiz of COMMAND
- Mov BX, Offset ParamBlock ; ES:BX = parameter block
- Mov AX, 4B00h ; EXEC function call
- Int 21h ; Load command processor
-
- ; Return from COMMAND.COM
- ; -----------------------
-
- Mov AX, CS ; Current code segment
- Mov DS, AX ; Reset DS to this segment
- Mov ES, AX ; Reset ES to this segment
- Mov SS, AX ; Reset stack segment to it
- Mov SP, [StackPointer] ; Reset SP
- Pushf ; Save error flag
- Sub DL,DL ; Set Ctrl Break to OFF
- Mov AX,3301h
- Int 21h ; By calling DOS
- Popf ; Get back error flag
- Mov DX,Offset CommandMsg ; Set up possible error msg
- Jnc Terminate ; And print if EXEC error
-
- ; Unhide the Files, restore Ctrl-Break state, and exit
- ; ----------------------------------------------------
-
- ErrorExit2: Mov AH,9 ; Will print the string
- Int 21h ; Print it
- Terminate: Mov BL, 0FDh ; AND value for change
- Mov BH, 00h ; OR value for change
- Call ChangeFileMode ; Change file attributes
- Mov DL,[BreakState] ; Original break-state
- Mov AX,3301h ; Change the break-state
- Int 21h ; by calling DOS
- Int 20h ; Terminate
-
- ; SUBROUTINE: Change File Mode (All files, BL = AND, BH = OR)
- ; -----------------------------------------------------------
-
- ChangeFileMode: Mov CX, [FileCount] ; Number of files
- Jcxz EndOfChange ; If no files, do nothing
- Mov SI, [FileList] ; Beginning of list
- Mov DX, [FileListEnd] ; End of List
- ChangeLoop: Push SI ; Save pointer
- Mov SI, Offset FullPath ; Preceeding path string
- Mov DI, DX ; Destination of full name
- Call AsciizTransfer ; Transfer it
- Dec DI ; Back up to end zero
- Pop SI ; Get back pointer to filename
- Call AsciizTransfer ; Transfer it
- Push CX ; Save the counter
- Mov AX, 4300h ; Get attribute
- Int 21h ; by calling DOS
- And CL, BL ; AND with BL
- Or CL, BH ; OR with BH
- Mov AX, 4301h ; Now set attribute
- Int 21h ; by calling DOS
- Pop CX ; Get back counter
- Loop ChangeLoop ; And do it again if necessary
- EndOfChange: Ret ; End of subroutine
-
- ; SUBROUTINE: Asciiz String Transfer (SI, DI in, returned incremented)
- ; --------------------------------------------------------------------
-
- AsciizTransfer: Movsb ; Transfer Byte
- Cmp Byte Ptr [DI - 1], 0 ; See if it was end
- Jnz AsciizTransfer ; If not, loop
- Ret ; Or leave subroutine
-
- ; Variable length data stored at end
- ; ----------------------------------
-
- DTABuffer Label Byte ; For file find calls
- FullPath equ DTABuffer + 43 ; For file path and names
- CSEG EndS ; End of the segment
- End Entry ; Denotes entry point